package com.xudu.tourbackend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.xudu.tourbackend.common.globalEnum.ErrorCode;
import com.xudu.tourbackend.entity.Route;
import com.xudu.tourbackend.entity.ScenicArea;
import com.xudu.tourbackend.entity.ScenicSpot;
import com.xudu.tourbackend.entity.request.AddScenicAreaRequest;
import com.xudu.tourbackend.entity.request.SearchScenicAreaRequest;
import com.xudu.tourbackend.entity.request.UpdateScenicAreaRequest;
import com.xudu.tourbackend.entity.vo.ScenicAreaVo;
import com.xudu.tourbackend.exception.ServiceException;
import com.xudu.tourbackend.mapper.ScenicAreaMapper;
import com.xudu.tourbackend.mapper.ScenicSpotMapper;
import com.xudu.tourbackend.service.IRouteService;
import com.xudu.tourbackend.service.IScenicAreaService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xudu.tourbackend.service.IUserService;
import com.xudu.tourbackend.utils.QiniuUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author xudu
 * @since 2024-06-17
 */
@Service
public class ScenicAreaServiceImpl extends ServiceImpl<ScenicAreaMapper, ScenicArea> implements IScenicAreaService {

    @Resource
    private ScenicAreaMapper scenicAreaMapper;

    @Resource
    private ScenicSpotMapper scenicSpotMapper;

    @Resource
    private QiniuUtil qiniuUtil;

    @Resource
    private IUserService userService;

    @Resource
    private IRouteService routeService;

    @Override
    public int addScenicArea(AddScenicAreaRequest addScenicAreaRequest, HttpServletRequest request) {
        // 判断是否是管理员
        Boolean b = userService.isAdmin(request);
        if (!b) {
            throw new ServiceException(ErrorCode.NO_AUTH);
        }

        // 获取参数
        String scenicAreaName = addScenicAreaRequest.getScenicAreaName();
        if (StringUtils.isBlank(scenicAreaName)) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }
        Double scenicAreaLongitude = addScenicAreaRequest.getScenicAreaLongitude();
        if (scenicAreaLongitude == null) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }
        Double scenicAreaLatitude = addScenicAreaRequest.getScenicAreaLatitude();
        if (scenicAreaLatitude == null) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }
        String scenicAreaInfo = addScenicAreaRequest.getScenicAreaInfo();
        if (StringUtils.isBlank(scenicAreaInfo) || scenicAreaInfo.length() > 500) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }
        MultipartFile scenicAreaImage = addScenicAreaRequest.getScenicAreaImage();
        if (scenicAreaImage == null) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }
        MultipartFile scenicAreaVoice = addScenicAreaRequest.getScenicAreaVoice();
        if (scenicAreaVoice == null){
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }

        // 封装参数
        ScenicArea scenicArea = new ScenicArea();
        scenicArea.setScenicAreaName(scenicAreaName);
        scenicArea.setScenicAreaLongitude(scenicAreaLongitude);
        scenicArea.setScenicAreaLatitude(scenicAreaLatitude);
        scenicArea.setScenicAreaInfo(scenicAreaInfo);
        scenicArea.setScenicAreaImage(qiniuUtil.upload(scenicAreaImage));
        scenicArea.setScenicAreaVoice(qiniuUtil.upload(scenicAreaVoice));

        boolean save = this.save(scenicArea);
        if (!save) {
            throw new ServiceException(ErrorCode.SYSTEM_ERROR);
        }

        return scenicArea.getId();
    }

    @Override
    public IPage<ScenicAreaVo> searchScenicArea(SearchScenicAreaRequest searchScenicAreaRequest) {
        //查询景区，关联查询景区对应的景点
        QueryWrapper<ScenicArea> queryWrapper = new QueryWrapper<>();

        Integer id = searchScenicAreaRequest.getId();
        if (id != null && id > 0) {
            queryWrapper.lambda().eq(ScenicArea::getId, id);
        }
        String scenicAreaName = searchScenicAreaRequest.getScenicAreaName();
        if (StringUtils.isNotBlank(scenicAreaName)){
            queryWrapper.lambda().like(ScenicArea::getScenicAreaName, scenicAreaName);
        }
        Double scenicAreaLatitude = searchScenicAreaRequest.getScenicAreaLatitude();
        if (scenicAreaLatitude != null){
            queryWrapper.lambda().eq(ScenicArea::getScenicAreaLatitude, scenicAreaLatitude);
        }
        Double scenicAreaLongitude = searchScenicAreaRequest.getScenicAreaLongitude();
        if (scenicAreaLongitude != null){
            queryWrapper.lambda().eq(ScenicArea::getScenicAreaLongitude, scenicAreaLongitude);
        }
        String scenicAreaInfo = searchScenicAreaRequest.getScenicAreaInfo();
        if (StringUtils.isNotBlank(scenicAreaInfo)){
            queryWrapper.lambda().like(ScenicArea::getScenicAreaInfo, scenicAreaInfo);
        }
        List<ScenicArea> ScenicAreaList = this.list(queryWrapper);
        //如果没查到，请求参数错误（数据库中没有符合条件的数据）
        if (ScenicAreaList.isEmpty()){
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }
        Page<ScenicArea> page = new Page<>(searchScenicAreaRequest.getPageNum(),searchScenicAreaRequest.getPageSize());
        Page<ScenicArea> scenicAreaPage = this.page(page, queryWrapper);
        List<ScenicAreaVo> scenicAreaVoList = new ArrayList<>();
        scenicAreaPage.getRecords().forEach(scenicArea -> {
            QueryWrapper<ScenicSpot> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.lambda().eq(ScenicSpot::getScenicAreaId, scenicArea.getId());
            ScenicAreaVo scenicAreaVo = new ScenicAreaVo();
            BeanUtils.copyProperties(scenicArea, scenicAreaVo);
            scenicAreaVo.setSpots(scenicSpotMapper.selectList(queryWrapper1));
            scenicAreaVoList.add(scenicAreaVo);
        });

        Page<ScenicAreaVo> scenicAreaVoPage = new Page<>(scenicAreaPage.getCurrent(),scenicAreaPage.getSize(),scenicAreaPage.getTotal());
        scenicAreaVoPage.setRecords(scenicAreaVoList);


        return scenicAreaVoPage;

    }

    @Override
    public List<ScenicAreaVo> searchScenicArea(String scenicAreaName) {

        QueryWrapper<ScenicArea> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(scenicAreaName)){
            queryWrapper.lambda().like(ScenicArea::getScenicAreaName, scenicAreaName);
        }

        //queryWrapper.lambda().like(ScenicArea::getScenicAreaName, scenicAreaName);
        List<ScenicArea> scenicAreaList = scenicAreaMapper.selectList(queryWrapper);
        if (scenicAreaList.isEmpty()) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }

        ArrayList<ScenicAreaVo> scenicAreaVoList = new ArrayList<>();

        for (int i = 0; i < scenicAreaList.size(); i++) {
            ScenicArea scenicArea = scenicAreaList.get(i);
            ScenicAreaVo scenicAreaVo = new ScenicAreaVo();
            BeanUtils.copyProperties(scenicArea, scenicAreaVo);

            QueryWrapper<ScenicSpot> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.lambda().eq(ScenicSpot::getScenicAreaId, scenicArea.getId());
            List<ScenicSpot> scenicSpots = scenicSpotMapper.selectList(queryWrapper1);
            scenicAreaVo.setSpots(scenicSpots);
            scenicAreaVoList.add(scenicAreaVo);
        }

        return scenicAreaVoList;
    }

    @Override
    public Boolean updateScenicArea(UpdateScenicAreaRequest updateScenicAreaRequest, HttpServletRequest request) {

        Boolean b = userService.isAdmin(request);
        if (!b) {
            throw new ServiceException(ErrorCode.NO_AUTH);
        }

        Integer id = updateScenicAreaRequest.getId();
        if (id <= 0 || scenicAreaMapper.selectById(id) == null){
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }

        ScenicArea scenicArea = new ScenicArea();
        BeanUtils.copyProperties(updateScenicAreaRequest, scenicArea);

        //如果更新的请求参数中有图片，则删除原来的图片，有语音，则删除原来的语音
        MultipartFile scenicAreaImage = updateScenicAreaRequest.getScenicAreaImage();
        if (scenicAreaImage != null) {
            qiniuUtil.deleteFile(scenicAreaMapper.selectById(id).getScenicAreaImage());
            scenicArea.setScenicAreaImage(qiniuUtil.upload(scenicAreaImage));
        }
        MultipartFile scenicAreaVoice = updateScenicAreaRequest.getScenicAreaVoice();
        if (scenicAreaVoice != null) {
            qiniuUtil.deleteFile(scenicAreaMapper.selectById(id).getScenicAreaVoice());
            scenicArea.setScenicAreaVoice(qiniuUtil.upload(scenicAreaVoice));
        }
        return this.updateById(scenicArea);

    }

    @Override
    @Transactional(rollbackFor = Exception.class) //操作多个数据库表的时候防止个别数据库表操作失败，一起成功或者一起失败
    public int deleteScenicArea(List<Integer> ids, HttpServletRequest request) {
        if (ids.isEmpty()){
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }

        Boolean b = userService.isAdmin(request);
        if (!b) {
            throw new ServiceException(ErrorCode.NO_AUTH);
        }

        for (Integer id : ids){
            //关联删除包含该景点的路线中的景区信息
            List<Route> list = routeService.list();
            for (Route route : list){
                String alongScenics = route.getAlongScenics();
                Gson gson = new Gson();
                List<Integer> alongScenicsList = gson.fromJson(alongScenics, new TypeToken<List<Integer>>() {}.getType());
                if (alongScenicsList.contains(id)){
                    alongScenicsList.remove(id);
                    route.setAlongScenics(gson.toJson(alongScenicsList));
                    route.setUpdateTime(null);
                    routeService.updateById(route);
                }
            }
            //关联删除该景区的所有景点
            QueryWrapper<ScenicSpot> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(ScenicSpot::getScenicAreaId, id);
            scenicSpotMapper.delete(queryWrapper);
        }



        int i = scenicAreaMapper.deleteBatchIds(ids);
        if (i <= 0) {
            throw new ServiceException(ErrorCode.SYSTEM_ERROR);
        }
        return i;
    }
}
